package com.trade.common.utils.net;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.trade.common.utils.*;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.io.*;
import java.util.*;

/**
 * HttpClient工具类
 * 使用 HttpClient 需要以下 6 个步骤：
 * 1. 创建 HttpClient 的实例
 * 2. 创建某种连接方法的实例
 * 3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例
 * 4. 读 response
 * 5. 释放连接。无论执行方法是否成功，都必须释放连接
 * 6. 对得到后的内容进行处理
 */
public class HttpClientUtil {
    private static Logger log = Logger.getLogger(HttpClientUtil.class);

    private static int timeOut = 2000000;

    /**
     * 发送post请求--基础方法
     *
     * @param url                      请求地址
     * @param inEntity                 请求参数
     * @param headers                  头信息
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param username                 用户名
     * @param password                 用户密码
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @return responseContent 远程主机响应正文
     */
    public static String postWithAuthentication(String url, HttpEntity inEntity, Map<String, String> headers, String decodeCharset,
                                                String username, String password,
                                                int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        String responseContent = "";
        //创建 HttpClient 的实例
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpClient httpClient = new HttpClient();
        responseContent = doPost(url, inEntity, headers, decodeCharset, socketTimeout, connectTimeout, connectionRequestTimeout, responseContent, httpclient);
        return responseContent;
    }

    private static String getResponseContent(String decodeCharset, String responseContent, CloseableHttpResponse response) throws IOException {
        try {
            //获取返回值
            HttpEntity outEntity = response.getEntity();
            if (outEntity != null) {
                responseContent = EntityUtils.toString(outEntity, decodeCharset == null ? "UTF-8" : decodeCharset);
            }
            //销毁HttpEntity
            EntityUtils.consume(outEntity);
        } finally {
            //关闭请求
            response.close();
        }
        return responseContent;
    }

    /**
     * 发送post请求-Form格式
     *
     * @param url                      请求地址
     * @param pmap                     请求参数
     * @param headers                  header信息
     * @param encodeCharset            编码字符集,默认UTF-8
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @return responseContent 远程主机响应正文
     */
    public static String postForm(String url, Map<String, String> pmap, Map<String, String> headers,
                                  String encodeCharset, String decodeCharset,
                                  int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        try {
            //入参
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            for (String key : pmap.keySet()) {
                nvps.add(new BasicNameValuePair(key, pmap.get(key)));
            }
            UrlEncodedFormEntity formEntity =
                    new UrlEncodedFormEntity(nvps, encodeCharset == null ? "UTF-8" : encodeCharset);
            //调用
            return HttpClientUtil.post(url, formEntity, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 发送post请求-Form格式
     *
     * @param url  请求地址
     * @param pmap 请求参数
     * @return responseContent 远程主机响应正文
     */
    public static String postForm(String url, Map<String, String> pmap) {
        return HttpClientUtil.postForm(url, pmap, new HashMap<String, String>(), "UTF-8", "UTF-8", timeOut, timeOut, timeOut);
    }


    /**
     * 发送post请求-JSON格式
     *
     * @param url                      请求地址
     * @param params                   请求参数
     * @param headers                  header数据
     * @param encodeCharset            编码字符集,默认UTF-8
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param contentType              内容类型
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @return responseContent 远程主机响应正文
     */
    public static String post(String url, Map<String, String> params, Map<String, String> headers,
                              String encodeCharset, String decodeCharset, String contentType,
                              int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        try {
            //入参
            StringEntity stringEntity = new StringEntity(JSON.toJSONString(params), encodeCharset);
            //stringEntity.setContentType(contentType);
            stringEntity.setContentEncoding(encodeCharset);
            //调用
            return HttpClientUtil.post(url, stringEntity, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 描述：HttpClient请求--POST方式--基础方法
     *
     * @param url         请求地址
     * @param requestData 请求参数
     * @return Map格式（status：返回代码，responseData：返回数据）
     * @throws Exception
     */
    public static Map<String, Object> post(String url, String requestData, String contentType) throws Exception {
        Map<String, Object> retMap = new HashMap<String, Object>();
        try {
            HttpClient httpClient = new HttpClient();
            PostMethod postMethod = new PostMethod(url);
            if (contentType != null && !contentType.equals("")) {
                postMethod.setRequestHeader("Content-Type", contentType + "; charset=UTF-8");
            }
            RequestEntity requestEntity = new StringRequestEntity(requestData, "text/xml", "UTF-8");
            postMethod.setRequestEntity(requestEntity);
//			postMethod.setRequestEntity(new InputStreamRequestEntity(new ByteArrayInputStream(requestData.getBytes())));
            int status = httpClient.executeMethod(postMethod);
            String responseData = postMethod.getResponseBodyAsString();
            retMap.put("status", status);
            retMap.put("responseData", responseData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retMap;
    }

    /**
     * 描述：调用URL通用httpClient方法（适用spring注解@ResponseBody、@RequestBody的方法）
     *
     * @param url  请求地址
     * @param pmap 参数（JSON格式）
     * @return Map<String, Object>
     */
    public static String callUrlFromJson(String url, Map<String, Object> pmap) {
        Map<String, Object> retMap = new HashMap<String, Object>();
        try {
            //调用接口
            Map<String, Object> responseMap = HttpClientUtil.post(url, JSON.toJSONString(pmap), "application/json");

            if (responseMap != null) {
                int status = YjhhUtil.toInt(responseMap.get("status"));
                String responseData = YjhhUtil.toString(responseMap.get("responseData"));
                if (status == 200) {
                    //将responseData转换成Map格式
                    if (!responseData.equals("")) {
                        return responseData;
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 发送post请求-JSON格式
     *
     * @param url       请求地址
     * @param params    请求参数
     * @param isRaw     是否raw发送
     * @param tenantId  租户ID
     * @param userId    用户ID
     * @param sessionId 用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String post(String url, Map<String, Object> params, boolean isRaw,
                              String tenantId, String userId, String sessionId) {
        return HttpClientUtil.post(url, params, isRaw, "UTF-8", "UTF-8", timeOut, timeOut, timeOut,
                tenantId, userId, sessionId);
    }

    /**
     * 发送post请求-JSON格式
     *
     * @param url                      请求地址
     * @param params                   请求参数
     * @param isRaw                    是否raw发送
     * @param encodeCharset            编码字符集,默认UTF-8
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @param tenantId                 租户ID
     * @param userId                   用户ID
     * @return responseContent 远程主机响应正文
     */
    public static String post(String url, Map<String, Object> params, boolean isRaw,
                              String encodeCharset, String decodeCharset,
                              int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                              String tenantId, String userId, String sessionId) {
        try {
            //入参
            StringEntity stringEntity = setStringEntity(params, isRaw, encodeCharset);
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json; charset=UTF-8");
            if (XaUtil.isNotEmpty(tenantId)) {
                headers.put(Constants.SERVICE_PROXY_TENANT_ID, tenantId);
            }
            if (XaUtil.isNotEmpty(userId)) {
                headers.put(Constants.SERVICE_PROXY_USER_ID, userId);
            }
            if (XaUtil.isNotEmpty(sessionId)) {
                headers.put(Constants.SERVICE_PROXY_USER_SESSION_ID, sessionId);
            }
            //调用
            return HttpClientUtil.post(url, stringEntity, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.toJSONString(new ResponseBean(ResponseUtil.REQUEST_ERROR_400, ResponseUtil.getMsg(ResponseUtil.REQUEST_ERROR_400)));
    }

    /**
     *  开放接口，发送post请求-JSON格式
     *
     * @param url                      请求地址
     * @param params                   请求参数
     * @param isRaw                    是否raw发送
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @param clientId                 客户端ID
     * @param key                      客户端Key
     * @return responseContent 远程主机响应正文
     */
    public static String post(String url, Map<String, Object> params, boolean isRaw,
                              int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                              String clientId, String key) {
        try {
            String charset = "UTF-8";
            //入参
            StringEntity stringEntity = setStringEntity(params, isRaw, charset);
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json; charset=UTF-8");
            if (XaUtil.isNotEmpty(clientId)) {
                headers.put(Constants.OPEN_API_PARAM_CLIENT_ID, clientId);
            }
            if (XaUtil.isNotEmpty(key)) {
                headers.put(Constants.OPEN_API_PARAM_KEY, key);
            }
            //调用
            return HttpClientUtil.post(url, stringEntity, headers, charset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.toJSONString(new ResponseBean(ResponseUtil.REQUEST_ERROR_400, ResponseUtil.getMsg(ResponseUtil.REQUEST_ERROR_400)));
    }

    private static StringEntity setStringEntity(Map<String, Object> params, boolean isRaw, String charset) {
        StringEntity stringEntity = null;
        if (null != params && params.size() > 0) {
            stringEntity = new StringEntity(JSON.toJSONString(params), charset);
            if (isRaw) {
                stringEntity.setContentType("application/json");
                stringEntity.setContentEncoding(charset);
            }
        }
        return stringEntity;
    }

    /**
     * 发送post请求--基础方法
     *
     * @param url                      请求地址
     * @param inEntity                 请求参数
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @return responseContent 远程主机响应正文
     */
    public static String post(String url, HttpEntity inEntity, Map<String, String> headers, String decodeCharset,
                              int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        String responseContent = "";
        //创建 HttpClient 的实例
        CloseableHttpClient httpclient = HttpClients.createDefault();
        responseContent = doPost(url, inEntity, headers, decodeCharset, socketTimeout, connectTimeout, connectionRequestTimeout, responseContent, httpclient);
        return responseContent;
    }

    private static String doPost(String url, HttpEntity inEntity, Map<String, String> headers, String decodeCharset, int socketTimeout, int connectTimeout, int connectionRequestTimeout, String responseContent, CloseableHttpClient httpclient) {
        try {
            //创建post连接方法的实例
            HttpPost httpPost = new HttpPost(url);
            // Request 配置
            RequestConfig requestConfig = RequestConfig.copy(RequestConfig.DEFAULT) //
                    .setSocketTimeout(socketTimeout) //响应超时
                    .setConnectTimeout(connectTimeout) //连接超时
                    .setConnectionRequestTimeout(connectionRequestTimeout) //请求超时
                    .build();
            httpPost.setConfig(requestConfig);
            //设置参数
            if (XaUtil.isNotEmpty(inEntity)) {
                httpPost.setEntity(inEntity);
            }
            //设置header
            for (String headerKey : headers.keySet()) {
                httpPost.setHeader(headerKey, headers.get(headerKey));
            }
            //执行请求
            CloseableHttpResponse response = httpclient.execute(httpPost);
            responseContent = getResponseContent(decodeCharset, responseContent, response);
        } catch (Exception e) {
            log.error("request post method exception:", e);
            e.printStackTrace();
        } finally {
            //关闭实例
            try {
                httpclient.close();
            } catch (IOException e) {
                log.error("Close post method exception:", e);
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    // ***************************** get method start *********

    public static String get(String url, String tenantId, String userId, String sessionId) {
        return HttpClientUtil.get(url, "UTF-8", "UTF-8", timeOut, timeOut, timeOut,
                tenantId, userId, sessionId);
    }

    /**
     * 发送GET请求
     *
     * @param url                      请求地址
     * @param encodeCharset            编码字符集,默认UTF-8
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @param tenantId                 租户ID
     * @param userId                   用户ID
     * @param sessionId                用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String get(String url, String encodeCharset, String decodeCharset,
                             int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                             String tenantId, String userId, String sessionId) {
        try {
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            /*headers.put("Content-Type", "application/json; charset=UTF-8");
            httpget.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.2)");
            // 用逗号分隔显示可以同时接受多种编码
            httpget.setHeader("Accept-Language", "zh-cn,zh;q=0.5");
            httpget.setHeader("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");*/
            if (XaUtil.isNotEmpty(tenantId)) {
                headers.put(Constants.SERVICE_PROXY_TENANT_ID, tenantId);
            }
            if (XaUtil.isNotEmpty(userId)) {
                headers.put(Constants.SERVICE_PROXY_USER_ID, userId);
            }
            if (XaUtil.isNotEmpty(sessionId)) {
                headers.put(Constants.SERVICE_PROXY_USER_SESSION_ID, sessionId);
            }
            //调用
            return HttpClientUtil.doGet(url, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.toJSONString(new ResponseBean(ResponseUtil.REQUEST_ERROR_400, ResponseUtil.getMsg(ResponseUtil.REQUEST_ERROR_400)));
    }

    /**
     * 开放接口，发送GET请求
     *
     * @param url                      请求地址
     * @param socketTimeout            响应超时，默认:2000000
     * @param connectTimeout           连接超时，默认:2000000
     * @param connectionRequestTimeout 请求超时，默认:2000000
     * @param clientId                 客户端ID
     * @param key                      客户端密钥
     * @return responseContent 远程主机响应正文
     */
    public static String get(String url,
                             int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                             String clientId, String key) {
        try {
            String decodeCharset = "UTF-8";
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            if (XaUtil.isNotEmpty(clientId)) {
                headers.put(Constants.OPEN_API_PARAM_CLIENT_ID, clientId);
            }
            if (XaUtil.isNotEmpty(key)) {
                headers.put(Constants.OPEN_API_PARAM_KEY, key);
            }
            //调用
            return HttpClientUtil.doGet(url, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.toJSONString(new ResponseBean(ResponseUtil.REQUEST_ERROR_400, ResponseUtil.getMsg(ResponseUtil.REQUEST_ERROR_400)));
    }

    private static String doGet(String url, Map<String, String> headers, String decodeCharset, int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        String responseContent = "";
        //创建 HttpClient 的实例
        CloseableHttpClient httpclient = null;
        try {
            //创建 HttpClient 的实例
            httpclient = HttpClients.createDefault();
            //创建post连接方法的实例
            HttpGet httpGet = new HttpGet(url);
            // Request 配置
            RequestConfig requestConfig = RequestConfig.copy(RequestConfig.DEFAULT) //
                    .setSocketTimeout(socketTimeout) //响应超时
                    .setConnectTimeout(connectTimeout) //连接超时
                    .setConnectionRequestTimeout(connectionRequestTimeout) //请求超时
                    .build();
            httpGet.setConfig(requestConfig);
            //设置header
            for (String headerKey : headers.keySet()) {
                httpGet.setHeader(headerKey, headers.get(headerKey));
            }
            //执行请求
            CloseableHttpResponse response = httpclient.execute(httpGet);
            responseContent = getResponseContent(decodeCharset, responseContent, response);
        } catch (Exception e) {
            log.error("request get method exception:", e);
            e.printStackTrace();
        } finally {
            //关闭实例
            try {
                if (httpclient != null) {
                    httpclient.close();
                }
            } catch (IOException e) {
                log.error("Close get method exception:", e);
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    /**
     * get请求文件
     *
     * @param url
     * @param filepath 文件下载路径
     * @param tenantId 租户ID
     * @param userId   用户ID
     * @param sessionId 用户会话
     */
    public static void getWithFile(String url, String filepath, String tenantId, String userId, String sessionId) {
        HttpClientUtil.getWithFile(url, filepath, "UTF-8", "UTF-8", timeOut, timeOut, timeOut, tenantId, userId, sessionId);
    }

    /**
     * 发送GET请求文件
     *
     * @param url                      请求地址
     * @param filepath                 文件下载路径
     * @param encodeCharset            编码字符集,默认UTF-8
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     */
    public static void getWithFile(String url, String filepath,
                                   String encodeCharset, String decodeCharset,
                                   int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                                   String tenantId, String userId, String sessionId) {
        try {
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            if (XaUtil.isNotEmpty(tenantId)) {
                headers.put(Constants.SERVICE_PROXY_TENANT_ID, tenantId);
            }
            if (XaUtil.isNotEmpty(userId)) {
                headers.put(Constants.SERVICE_PROXY_USER_ID, userId);
            }
            if(XaUtil.isNotEmpty(sessionId)){
                headers.put(Constants.SERVICE_PROXY_USER_SESSION_ID, sessionId);
            }
            //调用
            HttpClientUtil.doGetWithFile(url, filepath, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void doGetWithFile(String url, String filepath,
                                      Map<String, String> headers, String decodeCharset,
                                      int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        String responseContent = "";
        //创建 HttpClient 的实例
        CloseableHttpClient httpclient = null;
        InputStream is = null;
        try {
            //创建 HttpClient 的实例
            httpclient = HttpClients.createDefault();
            //创建post连接方法的实例
            HttpGet httpGet = new HttpGet(url);
            // Request 配置
            RequestConfig requestConfig = RequestConfig.copy(RequestConfig.DEFAULT) //
                    .setSocketTimeout(socketTimeout) //响应超时
                    .setConnectTimeout(connectTimeout) //连接超时
                    .setConnectionRequestTimeout(connectionRequestTimeout) //请求超时
                    .build();
            httpGet.setConfig(requestConfig);
            //设置header
            for (String headerKey : headers.keySet()) {
                httpGet.setHeader(headerKey, headers.get(headerKey));
            }
            //执行请求
            HttpResponse response = httpclient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
            int pos = url.lastIndexOf("/");
            String fileName = url.substring(pos + 1);
            File file = new File(filepath + File.separator + fileName);
            file.getParentFile().mkdirs();
            FileOutputStream fileOut = new FileOutputStream(filepath + File.separator + fileName);
            /**
             * 根据实际运行效果 设置缓冲区大小
             */
            byte[] buffer = new byte[2048];
            int ch = 0;
            while ((ch = is.read(buffer)) != -1) {
                fileOut.write(buffer, 0, ch);
            }
            is.close();
            fileOut.flush();
            fileOut.close();
        } catch (Exception e) {
            log.error("request get file method exception:", e);
            e.printStackTrace();
        } finally {
            //关闭实例
            try {
                if (httpclient != null) {
                    httpclient.close();
                }
            } catch (IOException e) {
                log.error("Close get file method exception:", e);
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取response header中Content-Disposition中的filename值
     *
     * @param response
     * @return
     */
    public static String getFileName(HttpResponse response) {
        Header contentHeader = response.getFirstHeader("Content-Disposition");
        String filename = null;
        if (contentHeader != null) {
            HeaderElement[] values = contentHeader.getElements();
            if (values.length == 1) {
                NameValuePair param = values[0].getParameterByName("filename");
                if (param != null) {
                    try {
                        //filename = new String(param.getValue().toString().getBytes(), "utf-8");
                        //filename=URLDecoder.decode(param.getValue(),"utf-8");
                        filename = param.getValue();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        if (filename == null) {
            filename = XaUtil.getTimestampStr();
        }
        return filename;
    }

    // ***************************** get file method end *********

    // ***************************** get delete start *********
    public static String delete(String url, String tenantId, String userId, String sessionId) {
        return HttpClientUtil.delete(url, "UTF-8", "UTF-8", timeOut, timeOut, timeOut,
                tenantId, userId, sessionId);
    }

    private static String delete(String url, String encodeCharset, String decodeCharset,
                                 int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                                 String tenantId, String userId, String sessionId) {
        try {
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            if (XaUtil.isNotEmpty(tenantId)) {
                headers.put(Constants.SERVICE_PROXY_TENANT_ID, tenantId);
            }
            if (XaUtil.isNotEmpty(userId)) {
                headers.put(Constants.SERVICE_PROXY_USER_ID, userId);
            }
            if (XaUtil.isNotEmpty(sessionId)) {
                headers.put(Constants.SERVICE_PROXY_USER_SESSION_ID, sessionId);
            }
            //调用
            String responseContent = "";
            responseContent = doDelete(url, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
            return responseContent;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.toJSONString(new ResponseBean(ResponseUtil.REQUEST_ERROR_400, ResponseUtil.getMsg(ResponseUtil.REQUEST_ERROR_400)));
    }

    private static String doDelete(String url, Map<String, String> headers, String decodeCharset, int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        String responseContent = "";
        //创建 HttpClient 的实例
        CloseableHttpClient httpclient = null;
        try {
            httpclient = HttpClients.createDefault();
            //创建delete连接方法的实例
            HttpDelete httpDel = new HttpDelete(url);
            // Request 配置
            RequestConfig requestConfig = RequestConfig.copy(RequestConfig.DEFAULT) //
                    .setSocketTimeout(socketTimeout) //响应超时
                    .setConnectTimeout(connectTimeout) //连接超时
                    .setConnectionRequestTimeout(connectionRequestTimeout) //请求超时
                    .build();
            httpDel.setConfig(requestConfig);
            //设置header
            for (String headerKey : headers.keySet()) {
                httpDel.setHeader(headerKey, headers.get(headerKey));
            }
            //执行请求
            CloseableHttpResponse response = httpclient.execute(httpDel);
            responseContent = getResponseContent(decodeCharset, responseContent, response);
        } catch (Exception e) {
            log.error("request delete method exception:", e);
            e.printStackTrace();
        } finally {
            //关闭实例
            try {
                httpclient.close();
            } catch (IOException e) {
                log.error("Close delete method exception:", e);
                e.printStackTrace();
            }
        }
        return responseContent;
    }
    // ***************************** get delete end *********

    // ***************************** get delete start *********
    public static String put(String url, Map<String, Object> pmap, String tenantId, String userId, String sessionId) {
        return HttpClientUtil.put(url, pmap, "UTF-8", "UTF-8", timeOut, timeOut, timeOut,
                tenantId, userId, sessionId);
    }

    /**
     * 发送post请求-JSON格式
     *
     * @param url                      请求地址
     * @param pmap                     请求参数
     * @param encodeCharset            编码字符集,默认UTF-8
     * @param decodeCharset            解码字符集,默认UTF-8
     * @param socketTimeout            响应超时
     * @param connectTimeout           连接超时
     * @param connectionRequestTimeout 请求超时
     * @return responseContent 远程主机响应正文
     */
    public static String put(String url, Map<String, Object> pmap, String encodeCharset, String decodeCharset,
                             int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                             String tenantId, String userId, String sessionId) {
        try {
            //入参
            StringEntity stringEntity = null;
            if (null != pmap && pmap.size() > 0) {
                stringEntity = new StringEntity(JSON.toJSONString(pmap), encodeCharset);
                stringEntity.setContentType("application/json");
                stringEntity.setContentEncoding(encodeCharset);
            }
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json; charset=UTF-8");
            if (XaUtil.isNotEmpty(tenantId)) {
                headers.put(Constants.SERVICE_PROXY_TENANT_ID, tenantId);
            }
            if (XaUtil.isNotEmpty(userId)) {
                headers.put(Constants.SERVICE_PROXY_USER_ID, userId);
            }
            if (XaUtil.isNotEmpty(sessionId)) {
                headers.put(Constants.SERVICE_PROXY_USER_SESSION_ID, sessionId);
            }
            //调用
            return HttpClientUtil.doPut(url, stringEntity, headers, decodeCharset, socketTimeout, connectTimeout,
                    connectionRequestTimeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.toJSONString(new ResponseBean(ResponseUtil.REQUEST_ERROR_400, ResponseUtil.getMsg(ResponseUtil.REQUEST_ERROR_400)));
    }

    private static String doPut(String url, HttpEntity inEntity, Map<String, String> headers, String decodeCharset, int socketTimeout, int connectTimeout, int connectionRequestTimeout) {
        String responseContent = "";
        //创建 HttpClient 的实例
        CloseableHttpClient httpclient = null;
        try {
            //创建 HttpClient 的实例
            httpclient = HttpClients.createDefault();
            //创建put连接方法的实例
            HttpPut httpPut = new HttpPut(url);
            // Request 配置
            RequestConfig requestConfig = RequestConfig.copy(RequestConfig.DEFAULT) //
                    .setSocketTimeout(socketTimeout) //响应超时
                    .setConnectTimeout(connectTimeout) //连接超时
                    .setConnectionRequestTimeout(connectionRequestTimeout) //请求超时
                    .build();
            httpPut.setConfig(requestConfig);
            //设置参数
            if (XaUtil.isNotEmpty(inEntity)) {
                httpPut.setEntity(inEntity);
            }
            //设置header
            for (String headerKey : headers.keySet()) {
                httpPut.setHeader(headerKey, headers.get(headerKey));
            }
            //执行请求
            CloseableHttpResponse response = httpclient.execute(httpPut);
            responseContent = getResponseContent(decodeCharset, responseContent, response);
        } catch (Exception e) {
            log.error("request put method exception:", e);
            e.printStackTrace();
        } finally {
            //关闭实例
            try {
                if (httpclient != null) {
                    httpclient.close();
                }
            } catch (IOException e) {
                log.error("Close put method exception:", e);
                e.printStackTrace();
            }
        }
        return responseContent;
    }
    // ***************************** get put end *********

    /**
     * post上传文件请求
     *
     * @param url       请求地址
     * @param params    请求参数
     * @param fileNames 文件集合
     * @param tenantId  租户ID
     * @param userId    用户ID
     * @param sessionId 用户会话ID
     * @return responseContent 远程主机响应正文
     */
    public static String postWithFiles(String url, Map<String, Object> params,
                                       String[] fileNames, String tenantId,
                                       String userId, String sessionId) {
        return HttpClientUtil.postWithFiles(url, params, fileNames, "UTF-8", "UTF-8", timeOut, timeOut, timeOut,
                tenantId, userId, sessionId);
    }

    public static String postWithFiles(String url, Map<String, Object> params,
                                       String[] fileNames, String encodeCharset, String decodeCharset,
                                       int socketTimeout, int connectTimeout, int connectionRequestTimeout,
                                       String tenantId, String userId, String sessionId) {
        try {
            //设置header
            Map<String, String> headers = new HashMap<String, String>();
            //headers.put("Content-Type", "application/json; charset=UTF-8");
            if (XaUtil.isNotEmpty(tenantId)) {
                headers.put(Constants.SERVICE_PROXY_TENANT_ID, tenantId);
            }
            if (XaUtil.isNotEmpty(userId)) {
                headers.put(Constants.SERVICE_PROXY_USER_ID, userId);
            }
            if(XaUtil.isNotEmpty(sessionId)){
                headers.put(Constants.SERVICE_PROXY_USER_SESSION_ID, sessionId);
            }
            String responseContent = "";
            CloseableHttpClient httpclient = HttpClients.createDefault();
            responseContent = doPostWithFiles(url, headers, params, fileNames,
                    decodeCharset, socketTimeout, connectTimeout, connectionRequestTimeout, responseContent, httpclient);
            return responseContent;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.toJSONString(new ResponseBean(ResponseUtil.REQUEST_ERROR_400, ResponseUtil.getMsg(ResponseUtil.REQUEST_ERROR_400)));
    }

    private static String doPostWithFiles(String url, Map<String, String> headers, Map<String, Object> params,
                                          String[] fileNames,
                                          String decodeCharset,
                                          int socketTimeout, int connectTimeout, int connectionRequestTimeout, String responseContent, CloseableHttpClient httpclient) {
        try {
            HttpPost httpPost = new HttpPost(url);
            // Request 配置
            RequestConfig requestConfig = RequestConfig.copy(RequestConfig.DEFAULT) //
                    .setSocketTimeout(socketTimeout) //响应超时
                    .setConnectTimeout(connectTimeout) //连接超时
                    .setConnectionRequestTimeout(connectionRequestTimeout) //请求超时
                    .build();
            httpPost.setConfig(requestConfig);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            for (int i = 0; i < fileNames.length; i++) {
                //FileBody fileBody = new FileBody(new File(fileNames[i]));
                File file = new File(fileNames[i]);
                builder.addBinaryBody("attachments" + i, file, ContentType.DEFAULT_BINARY, fileNames[i]);
            }
            Iterator<Map.Entry<String, Object>> it = params.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, Object> param = it.next();
                builder.addTextBody(param.getKey(), param.getValue() + "", ContentType.DEFAULT_BINARY);
            }
            //设置参数
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            //设置header
            for (String headerKey : headers.keySet()) {
                httpPost.setHeader(headerKey, headers.get(headerKey));
            }
            //执行请求
            CloseableHttpResponse response = httpclient.execute(httpPost);
            responseContent = getResponseContent(decodeCharset, responseContent, response);
        } catch (Exception e) {
            log.error("request post with files method exception:", e);
            e.printStackTrace();
        } finally {
            //关闭实例
            try {
                httpclient.close();
            } catch (IOException e) {
                log.error("Close post with files method exception:", e);
                e.printStackTrace();
            }
        }
        return responseContent;
    }
}
